home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 March / Macworld (1998-03) (Disk 1).dmg / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / tclMode.tcl < prev   
Encoding:
Text File  |  1997-12-13  |  35.0 KB  |  1,112 lines  |  [TEXT/ALFA]

  1. ## -*-Tcl-*- (install)
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "tclMode.tcl"
  6.  #                                 created: 6/8/95 {4:12:32 pm}
  7.  #                                 last update: 13/12/97 {12:45:59 pm}
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  # Copyright (c) 1997 Vince Darley
  15.  #  
  16.  #    Three procs from original: Tcl::DblClick listArray, getVarValue
  17.  #    
  18.  #    Adds support for Tk, Itcl keywords and completions, plus 
  19.  #    numerous fixes, improvements and integration with Vince's
  20.  #    Additions.
  21.  # ###################################################################
  22.  ##
  23.  
  24. alpha::mode Tcl 1.4 tclMenu {*.tcl *.itcl *.itk} tclMenu {
  25.     addMenu tclMenu "•269"
  26.     set unixMode(wish) {Tcl}
  27.     set unixMode(tclsh) {Tcl}
  28.     ensureset tclshSig "WIsH"
  29.     ensureset loadRemotely 0
  30.     trace variable loadRemotely w loadRemoteSynchronise
  31. } maintainer {
  32.     "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
  33. } uninstall this-file help {
  34.     This mode is for editing Tcl code.  You can edit code for internal
  35.     use with Alpha, or use Alpha as an external editor for code destined
  36.     for use with Tcl and Tk interpreters --- Sun distributes the Wish
  37.     application and a tcl-tk browser plugin.
  38.     
  39.     You can 'load' a procedure (or any Tcl code for that matter) to 
  40.     make changes on the fly.  If you select 'Load Remotely' in the 
  41.     tcl-tk submenu, then such actions will actually send the code
  42.     to a separately running Wish application to be evaluated.
  43. }
  44.  
  45.  
  46. proc tclMenu {} {}
  47.  
  48. # ◊◊◊◊ menu and prefs ◊◊◊◊ #
  49. # The menu.
  50. proc menu::buildtclMenu {} {
  51.     global tclMenu loadRemotely
  52.     set ma [list \
  53.       "/-<UswitchToTclsh" \
  54.       [list menu -n "tcl-tk" -p tcltk::menuProc [list \
  55.       "![lindex {{ } •} $loadRemotely]loadRemotely" \
  56.       executeCommand]] \
  57.       "(-" "/L<O<BloadProc" "/Z<O<BtraceThisProc" "/Z<O<UtraceTclProc…" \
  58.       "/D<O<UdumpTraces" "(-" "rebuildTclIndices" "(-" \
  59.       "<U/PfindProcDefinition…" "/P<IquickFindProc…" "getVarValue…" \
  60.       "insertMenuCodes…" "insertBindingCodes…" "/4<BaddRemoveDollars" \
  61.       "/3<BinsertDivider" "/8<I<BsurroundWithBullets"]
  62.     return [list build $ma Tcl::MenuProc "" $tclMenu]
  63. }
  64. menu::buildProc tclMenu menu::buildtclMenu
  65. menu::buildSome tclMenu
  66.  
  67. newPref v prefixString {# } Tcl
  68. newPref f wordWrap {0} Tcl
  69. newPref v funcExpr {^proc *([+-a-zA-Z0-9]+)} Tcl
  70. newPref v parseExpr {^proc *([+-a-zA-Z0-9]+)} Tcl
  71. newPref v wordBreak {(\$)?[\w:_]+} Tcl
  72. newPref v wordBreakPreface {([^\w:_\$]|.\$)} Tcl
  73. newPref f elecLBrace 1 Tcl
  74. newPref f elecRBrace 1 Tcl
  75. newPref f elecReturn 1 Tcl
  76. newPref f autoMark 0 Tcl
  77. newPref f electricTab 1 Tcl
  78. newPref v stringColor green Tcl
  79. newPref v commentColor red Tcl
  80. newPref v keywordColor blue Tcl
  81. newPref v alphaKeyWordColor    none Tcl stringColorProc
  82. newPref f recogniseTk 1 Tcl Tcl::_updateKeywords
  83. newPref f recogniseItcl 1 Tcl Tcl::_updateKeywords
  84. newPref f recognisePseudoTcl 1 Tcl Tcl::_updateKeywords
  85. newPref v indentSlashEndLines 1 Tcl "" indent::amounts varindex
  86. newPref f structuralMarks 0 Tcl
  87. set Tcl::startPara {^(.*\{)?[ \t]*(#|$)}
  88. set Tcl::endPara {^(.*\})?[ \t]*(#|$)}
  89.  
  90. ## 
  91.  # -------------------------------------------------------------------------
  92.  # 
  93.  # "Tcl::_updateKeywords" --
  94.  # 
  95.  #  This proc now includes support for optional separate colorization of 
  96.  #  alpha commands. To use, set 'alphaKeyWordColor' to something other than 
  97.  #  'none' in the Tcl Mode Preferences dialog. -trf
  98.  # -------------------------------------------------------------------------
  99.  ##
  100. proc Tcl::_updateKeywords {args} {
  101.     set tclKeyWords {
  102.         after append array auto_execok auto_load auto_mkindex 
  103.         auto_reset beep binary break case catch cd clock close concat 
  104.         continue echo eof error eval exit expr fblocked fconfigure 
  105.         fcopy file fileevent flush for foreach format gets glob global 
  106.         history if incr info interp join lappend lindex linsert list 
  107.         llength load lrange lreplace ls lsearch lsort namespace open 
  108.         package pid pkg_mkIndex proc puts pwd read regexp regsub 
  109.         rename resource return scan seek set socket source split 
  110.         string subst switch tclMacPkgSearch tclPkgSetup tclPkgUnknown 
  111.         tell time trace unknown unset update uplevel upvar variable 
  112.         vwait while scancontext else elseif default
  113.     }
  114.     
  115.     set alphaKeyWords {
  116.         abortEm abbrev addAlphaChars addMenuItem addDef addArrDef 
  117.         AEBuild alertnote alphaHelp ascii askyesno backColor backSpace 
  118.         backwardChar backwardCharSelect backwardDeleteWord 
  119.         backwardWord balance beginningBufferSelect beginningLineSelect 
  120.         beginningOfBuffer beginningOfLine bind blink breakIntoLines 
  121.         bringToFront buttonAlert capitalizeRegion capitalizeWord 
  122.         centerRedraw clear closeAll colors colorTriple copy cp 
  123.         createTagFile createTMark currentPosition cut decToHex 
  124.         deleteChar deleteMenuItem deleteModeBindings deleteSelection 
  125.         deleteWord describeBinding deleteText dialog dirs display 
  126.         displayMode dosc downcaseRegion downcaseWord dumpColors 
  127.         dumpMacro edit enableMenuItem endBufferSelect endKeyboardMacro 
  128.         endLineSelect endOfBuffer endOfLine enterSelection 
  129.         eventHandler exchangePointAndMark execAbbrev execute 
  130.         executeKeyboardMacro fileInfo fileRemove find findAgain 
  131.         findAgainBackward findFile findInNextFile findTag float 
  132.         floatShowHide forwardChar forwardCharSelect forwardWord 
  133.         freeMem get_directory getAscii getChar getModifiers getColors 
  134.         getfile getFileInfo getGeometry getline getMainDevice getMark 
  135.         getNamedMarks getPathName getPos getScrap getSelect getText 
  136.         getTMarks getWinInfo goto gotoMark gotoTMark hexToDec icon 
  137.         icURL icGetPref icOpen insertAscii insertColorEscape 
  138.         insertFile insertMenu insertPathName insertText insertToTop 
  139.         isearch iterationCount jumpToRegister keyAscii keyCode 
  140.         killLine killWindow largestPrefix launch lineStart 
  141.         listBindings listpick lookAt markHilite markMenuItem 
  142.         matchBrace matchIt maxPos menu message mkdir mousePos 
  143.         moveInsertionHere moveFile moveWin mtime nameFromAppl new 
  144.         nextLine nextLineSelect nextLineStart nextSentence nextWindow 
  145.         now oneSpace openLine otherPane pageBack pageForward pageSetup 
  146.         paste pointToRegister popd posToRowCol prefixChar previousLine 
  147.         prevLineSelect prevSentence prevWindow print processes prompt 
  148.         pushd putfile putScrap quit rectMarkHilite redo 
  149.         regModeKeywords removeArrDef removeDef removeFile removeMark 
  150.         removeMenu removeTMark replace replaceAll replace&FindAgain 
  151.         replaceString replaceText restoreVars revert rmdir rowColToPos 
  152.         rsearch save saveAs saveVars scrollDownLine scrollLeftCol 
  153.         scrollRightCol scrollUpLine search searchString select selEnd 
  154.         sendOpenEvent sendToBack setFileInfo setFontsTabs setMark 
  155.         setNamedMark setWinInfo shell shiftLeftRegion shiftRightRegion 
  156.         sizeWin sortMarks spacesToTabs specToPathName splitWindow 
  157.         startEscape startKeyboardMacro statusPrompt substituteVars 
  158.         switchTo tab tabsToSpaces tclFileCompletion tclResult 
  159.         thinkReference ticks toggleScrollbar traceFunc unascii unbind 
  160.         undo unfloat upcaseRegion upcaseWord version watchCursor wc 
  161.         winNames wrap wrapText xtclcmd yank zapInvisibles zoom
  162.     }
  163.  
  164.     set tkKeyWords {
  165.         bindtags button canvas checkbutton console destroy entry event focus 
  166.         font frame grab grid image menubutton pack place radiobutton raise 
  167.         scale scrollbar text tk tkwait toplevel winfo wm label listbox
  168.         menu
  169.     }
  170.     
  171.     set itclKeyWords {
  172.         @scope body class code component constructor define destructor hull 
  173.         import inherit itcl itk itk_component itk_initialize itk_interior 
  174.         itk_option iwidgets keep method private protected 
  175.         public
  176.     }
  177.     global TclmodeVars
  178.     # add Tk keywords
  179.     if {$TclmodeVars(recogniseTk)} {
  180.         set tclKeyWords [concat $tclKeyWords $tkKeyWords]
  181.     }
  182.     # add the [incr tcl] keywords
  183.     if {$TclmodeVars(recogniseItcl)} {
  184.         set tclKeyWords [concat $tclKeyWords $itclKeyWords]
  185.     }
  186.     if {$TclmodeVars(recognisePseudoTcl)} {
  187.         set tclKeyWords [concat $tclKeyWords "lunion lreverse lremove lunique car"]
  188.     }
  189.     # add user extras
  190.     global Tclwords
  191.     if {[info exists Tclwords]} {
  192.         set tclKeyWords [concat $tclKeyWords $Tclwords]
  193.     }
  194.     global Tclcmds
  195.     set Tclcmds { append array catch close concat continue elseif error
  196.     for foreach format lindex llength lrange lreplace lsearch lsort regexp 
  197.     regsub rename return string switch while }
  198.     if {$TclmodeVars(recogniseTk)} {
  199.         append Tclcmds {
  200.             tkButtonDown tkButtonEnter tkButtonInvoke tkButtonLeave 
  201.             tkButtonUp tkCancelRepeat tkCheckRadioInvoke tkDarken 
  202.             tkEntryAutoScan tkEntryBackspace tkEntryButton1 
  203.             tkEntryClosestGap tkEntryInsert tkEntryKeySelect 
  204.             tkEntryMouseSelect tkEntryNextWord tkEntryPaste 
  205.             tkEntryPreviousWord tkEntrySeeInsert tkEntrySetCursor 
  206.             tkEntryTranspose tkEventMotifBindings tkFDGetFileTypes 
  207.             tkFirstMenu tkFocusGroup_BindIn tkFocusGroup_BindOut 
  208.             tkFocusGroup_Create tkFocusGroup_Destroy tkFocusGroup_In 
  209.             tkFocusGroup_Out tkFocusOK tkListboxAutoScan 
  210.             tkListboxBeginExtend tkListboxBeginSelect tkListboxBeginToggle 
  211.             tkListboxCancel tkListboxDataExtend tkListboxExtendUpDown 
  212.             tkListboxMotion tkListboxSelectAll tkListboxUpDown tkMbButtonUp 
  213.             tkMbEnter tkMbLeave tkMbMotion tkMbPost tkMenuButtonDown 
  214.             tkMenuDownArrow tkMenuDup tkMenuEscape tkMenuFind 
  215.             tkMenuFindName tkMenuFirstEntry tkMenuInvoke tkMenuLeave 
  216.             tkMenuLeftArrow tkMenuMotion tkMenuNextEntry tkMenuNextMenu 
  217.             tkMenuRightArrow tkMenuUnpost tkMenuUpArrow tkMessageBox 
  218.             tkPostOverPoint tkRecolorTree tkRestoreOldGrab tkSaveGrabInfo 
  219.             tkScaleActivate tkScaleButton2Down tkScaleButtonDown 
  220.             tkScaleControlPress tkScaleDrag tkScaleEndDrag tkScaleIncrement 
  221.             tkScreenChanged tkScrollButton2Down tkScrollButtonDown 
  222.             tkScrollButtonUp tkScrollByPages tkScrollByUnits tkScrollDrag 
  223.             tkScrollEndDrag tkScrollSelect tkScrollStartDrag tkScrollToPos 
  224.             tkScrollTopBottom tkTabToWindow tkTearOffMenu tkTextAutoScan 
  225.             tkTextButton1 tkTextClosestGap tkTextInsert tkTextKeyExtend 
  226.             tkTextKeySelect tkTextNextPara tkTextNextPos tkTextNextWord 
  227.             tkTextPaste tkTextPrevPara tkTextPrevPos tkTextResetAnchor 
  228.             tkTextScrollPages tkTextSelectTo tkTextSetCursor 
  229.             tkTextTranspose tkTextUpDownLine tkTraverseToMenu 
  230.             tkTraverseWithinMenu tk_bisque tk_chooseColor tk_dialog 
  231.             tk_focusFollowsMouse tk_focusNext tk_focusPrev tk_getOpenFile 
  232.             tk_getSaveFile tk_messageBox tk_optionMenu tk_popup 
  233.             tk_setPalette tk_textCopy tk_textCut tk_textPaste
  234.         }
  235.     }
  236.  
  237.     if {$TclmodeVars(recogniseTk)} {
  238.         regModeKeywords -e {#} -c $TclmodeVars(commentColor) \
  239.           -s $TclmodeVars(stringColor) \
  240.           -k $TclmodeVars(keywordColor) Tcl $tclKeyWords 
  241.           # add this line if we can handle double 'magic chars'
  242.           #-m {tk} 
  243.     } else {
  244.         regModeKeywords -e {#} -c $TclmodeVars(commentColor) \
  245.           -s $TclmodeVars(stringColor) \
  246.           -k $TclmodeVars(keywordColor) Tcl $tclKeyWords 
  247.     }
  248.     if {$TclmodeVars(alphaKeyWordColor) != "none"} {
  249.         regModeKeywords -a -k $TclmodeVars(alphaKeyWordColor) Tcl $alphaKeyWords
  250.     }
  251. }
  252. # call it now
  253. Tcl::_updateKeywords
  254.  
  255. proc Tcl::MenuProc {menu item} {
  256.     switch -glob $item {
  257.         "traceThisProc" {
  258.             procs::traceProc [procs::findEnclosingName [getPos]]
  259.         }
  260.         "loadProc" {
  261.             procs::loadEnclosing [getPos]
  262.         }
  263.         "findProcDefinition" {
  264.             procs::findDefinition
  265.         }
  266.         "quickFindProc" {
  267.             # use the status line
  268.             procs::quickFindDefn
  269.         }
  270.         "switch*" {
  271.             set v "[string tolower [string range $item 8 end]]Sig"
  272.             global $v
  273.             app::launchFore [set $v]
  274.         }
  275.         default {
  276.             eval $item
  277.         }
  278.     }
  279. }
  280. namespace eval tcltk {}
  281.  
  282. proc tcltk::menuProc {menu item} {
  283.     switch $item {
  284.         "loadRemotely" {
  285.             global loadRemotely
  286.             set loadRemotely [expr 1 - $loadRemotely]
  287.         }
  288.         default {
  289.             global tclshSig
  290.             set cmd [getline "Please enter the script to send to tcl-tk"]
  291.             set res [AEBuild -r -t 30000 '$tclshSig' misc dosc ---- "“$cmd”"]
  292.             alertnote "Result was '$res'"
  293.         }
  294.     }
  295. }
  296.  
  297. proc loadRemoteSynchronise {args} {
  298.     global loadRemotely tclMenu
  299.     catch {markMenuItem "tcl-tk" loadRemotely $loadRemotely}
  300.     if $loadRemotely {
  301.         if {[info commands notRemoteLoad] == ""} {
  302.             rename load notRemoteLoad
  303.             ;proc load {} {remoteLoad}
  304.         }
  305.         menu::replaceRebuild tclMenu "•320"
  306.     } else {
  307.         if {[info commands notRemoteLoad] != ""} {
  308.             rename load {}
  309.             rename notRemoteLoad load
  310.         }
  311.         menu::replaceRebuild tclMenu "•269"
  312.     }
  313. }
  314.  
  315. proc remoteLoad {} {
  316.     global tclshSig
  317.     app::ensureRunning $tclshSig
  318.     set t [getSelect]
  319.     catch {dosc -c '${tclshSig}' -s $t} r
  320.     message "Remote reply: $r"
  321. }
  322. # ◊◊◊◊ Quick Find Proc… ◊◊◊◊ #
  323. # "Quick Find Proc…" handler and sub-proc:
  324. proc procs::quickFindDefn {} {
  325.     global __keysSoFar __startIndex
  326.     set __keysSoFar {}
  327.     set __startIndex 0
  328.     set __lastMatchsDisplayed {}
  329.     
  330.     message ""
  331.  
  332.     set patt ""
  333.     set pos [getPos]
  334.     
  335.     set res [statusPrompt "proc name: " procs::Comp]
  336.     message "Aborted: $patt"
  337.     goto $pos
  338. }
  339.  
  340. ## 
  341.  # -------------------------------------------------------------------------
  342.  # 
  343.  # "procs::Comp" --
  344.  # 
  345.  #  The mods to this proc are along the lines of the proc that provides 
  346.  #  acronym-epansion in latex. Here you just type and get a list in the 
  347.  #  statusline of all the commands known to tcl that start with whatever 
  348.  #  you have typed so far. Whenever the set of commands share a common 
  349.  #  prefix that goes beyond what you have typed the "letters-entered" 
  350.  #  portion of the statusline advances to include all the common letters 
  351.  #  (this means you have to be careful you don't re-enter them manually, as 
  352.  #  that will likely abort entry as no command will match).
  353.  #  
  354.  #  Once you have started entering characters, you are presented with the 
  355.  #  number of known cammands that start with those characters followed by 
  356.  #  s horizontal listing of as many of those commands that will fit on the 
  357.  #  line. These commands are separated by double spaces in order to make 
  358.  #  commands stand out as a whole to the eye (command with "::" in them 
  359.  #  are harder for the eyes to parse without this).
  360.  #  
  361.  #  At this point you either keep entering characters to narrow the matching 
  362.  #  commands, type a tab to scroll through the horizontal list, or type a 
  363.  #  numeral that corresponds to the position one of the visible commands in 
  364.  #  the horizontal list (which will then be looked-up).
  365.  #  
  366.  #  If you just keep entering characters til you narrow the list to one 
  367.  #  command, you might get down to a situation where the command you want 
  368.  #  out of the matches is contained in all the other matches. When this 
  369.  #  happens all you have to do is to type a <apace> and you will look-up 
  370.  #  that command.
  371.  #  
  372.  #  To make things easier, whenever a character is entered that would abort 
  373.  #  the procedure, it is first check to see if the upperCase version of 
  374.  #  tht character would not keep us for aborting. For example, if you had 
  375.  #  'page…' as the entered portion, your list would be: 
  376.  #  (pageBackward  pageForward  pageSetup), so entering 'B' or 'b' would 
  377.  #  lookup pageBackward for you.
  378.  #  
  379.  #  ToDo: 
  380.  #  • provide cushioning/alerting mechanism against aborting when the user 
  381.  #  does not notice that entered portion has been automatically extended. 
  382.  #  Perhaps, flash the statusline and color the automatically entered 
  383.  #  portion, and/or allow the rentering of the auto-entered portion. 
  384.  #  Of course insertColorEscape does not work in the statusline, but 
  385.  #  perhaps it would be possible figure out the escapes and enter them 
  386.  #  as literals via message.
  387.  #  • perhaps alter this so you have the option of deleting characters 
  388.  #  instead of aborting when you get no matches.
  389.  #  • perhaps provide a variant that inserts the found procName into your 
  390.  #  current cursor position instead of doing a look-up.
  391.  #  
  392.  #  Note: made one change, moved the "number found:" portion of the prompt 
  393.  #  outside the horizontal list so it is easy to visually parse the list 
  394.  #  to determine what nember to hit to make a choice from the list.
  395.  # -------------------------------------------------------------------------
  396.  ##
  397. proc procs::Comp {curr {key 0}} {
  398.     global __keysSoFar __startIndex __lastStartIndex __lastMatchsDisplayed 
  399.     set mod [getModifiers]
  400.     if {$mod && ($mod != 2)} {error ""}
  401.     if {[string first $key "\034\035\036\037"] >= 0} {error ""}
  402.  
  403.     upvar patt pat
  404.     if {$key == "\t"} {
  405.         set __lastStartIndex $__startIndex 
  406.         set pats [lsort [info commands ${pat}*]]
  407.         set pats [join [split $pats] "  "]
  408.         set msg "proc '$pat…' ($pats)"
  409.         if {[string length $msg] > 80} {
  410.             set numFound [llength $pats]
  411.             set nextIdx [expr $__startIndex + 1]
  412.             set msg "proc '$pat…' $numFound found: ([lindex $pats $__startIndex] … »tab"
  413.             while {($nextIdx < $numFound) && ([string length "$msg  [lindex $pats $nextIdx]"] <= 80)} {
  414.                 set matchsDisplayed [lrange $pats $__startIndex $nextIdx]
  415.                 incr nextIdx
  416.                 if {$nextIdx >= $numFound} {
  417.                     set more ""
  418.                 } else {
  419.                     set more "…"
  420.                 } 
  421.                 if {$__startIndex == 0} {
  422.                     set start ""
  423.                 } else {
  424.                     set start "…"
  425.                 } 
  426.                 set msg "proc '$pat…' $numFound found: ($start $matchsDisplayed $more) »tab"
  427.             }
  428.             if {$nextIdx >= [expr $numFound]} {
  429.                 set __lastStartIndex $__startIndex 
  430.                 set __startIndex 0
  431.             } else {
  432.                 set __lastStartIndex $__startIndex 
  433.                 set __startIndex [expr $nextIdx]
  434.             }
  435.         }
  436.         message $msg
  437.         set __lastMatchsDisplayed $matchsDisplayed
  438.         return {}
  439.     } 
  440.     if {$key == " "} {
  441.         set pats [join [split [lsort [info commands $__keysSoFar]] ] "  "]    
  442.     } elseif {([string first $key "123456789"] >= 0) && (![llength [info commands $__keysSoFar$key*]])} {
  443.         if {$key <= [llength $__lastMatchsDisplayed]} {
  444.             set pats [lindex "null $__lastMatchsDisplayed" $key]
  445.         } else {
  446.             error ""
  447.         } 
  448.     } else {
  449.         set pats [join [split [lsort [info commands $__keysSoFar$key*]] ] "  "]
  450.     } 
  451.     
  452.     set numFound [llength $pats]
  453.     if {!$numFound} {
  454.         # first we'll see if the user was just too lazy to shift the key
  455.         set pats [join [split [lsort [lsort [info commands $__keysSoFar[string toupper $key]*]]] ] "  "] 
  456.         set numFound [llength $pats]
  457.     } 
  458.     append __keysSoFar $key
  459.     set pat $__keysSoFar
  460.     switch $numFound {
  461.         0 {
  462.             error "No procs."
  463.             beep
  464.         }
  465.         1 {
  466.             set pat $pats
  467.             message "proc or command -- '$pat'"
  468.             # to handle Tcl and Alpha built in commands -trf
  469.             Tcl::DblClickHelper $pat
  470.             error ""
  471.         }
  472.         default {
  473.             set pat [largestPrefix $pats]
  474.             set __keysSoFar $pat
  475.             set matchsDisplayed $pats
  476.             set msg "proc '$pat…' ($matchsDisplayed)"
  477.             if {[string length $msg] > 80} {
  478.                 set matchsDisplayed [lindex $pats 0]
  479.                 set nextIdx 1
  480.                 set msg "proc '$pat…' $numFound found: ($matchsDisplayed …) »tab"
  481.                 while {($nextIdx < $numFound) && ([string length "$msg [lindex $pats $nextIdx]"] <= 80)} {
  482.                     append matchsDisplayed "  " [lindex $pats $nextIdx]
  483.                     incr nextIdx
  484.                     set msg "proc '$pat…' $numFound found: ($matchsDisplayed …) »tab"
  485.                 }
  486.                 if {$nextIdx > [expr $numFound]} {
  487.                     set __lastStartIndex $__startIndex 
  488.                     set __startIndex 0
  489.                 } else {
  490.                     set __lastStartIndex $__startIndex 
  491.                     set __startIndex [expr $nextIdx -1]
  492.                 }
  493.                 
  494.             } 
  495.             set __lastMatchsDisplayed $matchsDisplayed
  496.             message $msg 
  497.         }
  498.     }
  499.     return {}
  500. }
  501. # ◊◊◊◊ electric behaviour ◊◊◊◊ #
  502. proc Tcl::electricLeft {} {
  503.     if [literalChar] { insertText "\{"; return }
  504.     set pat {\}[ \t\r]*(else(if)?)[ \t\r]*$}
  505.     set p [getPos]
  506.     if { [set res [findPatJustBefore "\}" "$pat" $p word]] == "" } { 
  507.         insertText "\{"
  508.         return
  509.     }
  510.     # we have an if/else(if)/else
  511.     switch $word {
  512.         "else" {
  513.             replaceText [lindex $res 0] $p "\} $word \{\r"
  514.             bind::IndentLine
  515.         }
  516.         "elseif" {
  517.             replaceText [lindex $res 0] $p "\} $word \{"
  518.         }
  519.     }
  520. }
  521.     
  522. proc Tcl::electricRight {} {
  523.     if [literalChar] { insertText "\}"; return }
  524.     set p [getPos]
  525.     if { [regexp {[^ \t]} [getText [lineStart $p] $p]] } {
  526.         insertText "\}"
  527.         blink [matchIt "\}" [expr $p - 1]]
  528.         return
  529.     }
  530.     set start [lineStart $p]
  531.     insertText "\}"
  532.     createTMark tcl_er [getPos]
  533.     backwardChar
  534.     bind::IndentLine
  535.     gotoTMark tcl_er ; removeTMark tcl_er
  536.     bind::CarriageReturn
  537.     blink [matchIt "\}" [expr $start -1]]
  538. }
  539.  
  540. ## 
  541.  # -------------------------------------------------------------------------
  542.  # 
  543.  # "Tcl::correctIndentation" --
  544.  # 
  545.  #  Returns the correct indentation for the line containing $pos, if that
  546.  #  line were to contain ordinary characters only.  It is the 
  547.  #  responsibility of the calling procedure to ensure that if we are to
  548.  #  insert/have a line already, that that information is taken into
  549.  #  account, by passing in the argument 'next'
  550.  # -------------------------------------------------------------------------
  551.  ##
  552. proc Tcl::correctIndentation {pos {next ""}} {
  553.     global indent_amounts indentSlashEndLines
  554.     # preliminaries
  555.     if {[set beg [lineStart $pos]] == 0} { return 0 }
  556.     # if the current line is a comment, we have to check some
  557.     # special cases
  558.     if {[set next [string index $next 0]] == "\#"} {
  559.         set p [prevLineStart $beg]
  560.         set prev [text::firstNonWsLinePos $p]
  561.         if {[lookAt $prev] != "\#" || ($beg == 0)} {
  562.             # not a comment, so indent with code
  563.         } else {
  564.             set lwhite [posX $prev]
  565.             # it's a comment
  566.             if {[getText $prev [expr $prev + 2]] == "\#\#" && \
  567.                 [lookAt [expr $prev +2]] != "\#" } {
  568.                 # it's a comment paragraph
  569.                 incr lwhite 
  570.             }
  571.         }
  572.     }
  573.     if ![info exists lwhite] {
  574.         if ![catch {search -s -f 0 -r 1 -i 0 -m 0 {^[ \t]*[^\# \t\r\n]} [expr $beg-1]} lst] {
  575.             # Find the last non-comment line and get its leading whitespace    
  576.             set lwhite [posX [expr [lindex $lst 1] - 1]]
  577.             set pe1 [lookAt [expr $beg -2]]
  578.             set lst [lindex $lst 0]
  579.             set lastC [lookAt [lindex [search -s -f 0 -r 1 -i 0 -m 0 {[^ \t\r\n]} [expr [nextLineStart $lst] - 1]] 0]]
  580.             if {$next == "\}"} {
  581.                 incr lwhite $indent_amounts(-2)
  582.                 set pe2 [lookAt [expr [prevLineStart $beg] -2]]
  583.                 if {$pe1 == "\\"} {
  584.                     incr lwhite $indent_amounts(1)
  585.                 } else {
  586.                     if {$pe2 == "\\"} {
  587.                         incr lwhite $indent_amounts(-1)
  588.                     }
  589.                 }
  590.                 if {$lastC == "\{"} {incr lwhite $indent_amounts(2)}    
  591.             } else { 
  592.                 if {$pe1 == "\\"} {
  593.                     if {[lookAt [expr [prevLineStart $beg] -2]] != "\\"} {
  594.                         incr lwhite $indent_amounts($indentSlashEndLines)
  595.                     }
  596.                 } else {
  597.                     if {$lastC == "\{"} {incr lwhite $indent_amounts(2)}    
  598.                     if {[lookAt [expr $lst -2]] == "\\"} {
  599.                         incr lwhite $indent_amounts(-$indentSlashEndLines)
  600.                     }
  601.                 }
  602.             }
  603.         } else {
  604.             # basically failed in all the above, so keep current indentation
  605.             set lwhite [posX [text::firstNonWsLinePos $beg]]
  606.         }
  607.     }
  608.     return $lwhite
  609. }
  610.  
  611. ## 
  612.  # -------------------------------------------------------------------------
  613.  #   
  614.  # "Tcl::indentLine" --
  615.  #  
  616.  #  Indentation for Tcl mode.  Better and faster than the generic procedure
  617.  # -------------------------------------------------------------------------
  618.  ##
  619. proc Tcl::indentLine {} {
  620.     set beg [lineStart [getPos]]
  621.     set text [getText $beg [nextLineStart $beg]]
  622.     regexp {^[ \t]*} $text white
  623.     set next [expr $beg +[string length $white]]
  624.     set lwhite [Tcl::correctIndentation [getPos] [lookAt $next]]
  625.     
  626.     set lwhite [text::indentOf $lwhite]
  627.     if {$white != $lwhite} {
  628.         replaceText $beg $next $lwhite
  629.     }
  630.     goto [expr $beg + [string length $lwhite]]
  631. }
  632. # ◊◊◊◊ Tcl Menu support ◊◊◊◊ #
  633. proc procs::loadEnclosing {pos} {
  634.     if [catch {set p [procs::findEnclosing $pos proc 1] } ] {
  635.         loadLine $pos
  636.     } else {
  637.         eval select $p
  638.         uplevel \#0 load    
  639.     }
  640.     goto $pos
  641. }
  642.  
  643. proc procs::traceProc {func} {
  644.     global tclMenu
  645.     # if we're tracing already then clear it
  646.     if {[llength [traceFunc status]]>2} { traceTclProc }
  647.     traceFunc on $func ""
  648.     catch {markMenuItem $tclMenu {traceTclProc…} on}
  649.     catch {enableMenuItem $tclMenu dumpTraces on}
  650.     message "Tracing '$func'…"
  651. }
  652.  
  653. proc procs::findDefinition {} {
  654.     if {[llength [winNames]] && [string length [set sel [getSelect]]]} {
  655.         set func [listpick -L $sel -p {Proc?} [lsort -ignore [info procs]]]
  656.     } else {
  657.         set func [listpick -p {Proc?} [lsort -ignore [info procs]]]
  658.     }
  659.  
  660.     editMark [procs::find $func] $func
  661. }
  662.  
  663. proc insertMenuCodes {} {
  664.     insertText [prompt::getAKey]
  665. }
  666.  
  667. proc insertBindingCodes {} {
  668.     beep
  669.     keyCode
  670. }
  671.  
  672. proc addRemoveDollars {} {
  673.     set p [getPos]
  674.     backwardWord
  675.     if {[lookAt [getPos]] == "\$"} {
  676.         deleteChar
  677.         goto [expr $p -1]
  678.     } else {
  679.         insertText "\$"
  680.         goto [expr $p +1]
  681.     }
  682. }
  683.  
  684. ## 
  685.  # -------------------------------------------------------------------------
  686.  # 
  687.  # "insertDivider" --
  688.  # 
  689.  #  Modified from Vince's original to allow you to just select part of
  690.  #  an already written comment and turn it into a Divider. -trf
  691.  # -------------------------------------------------------------------------
  692.  ##
  693. proc insertDivider {} {
  694.     if {[isSelection]} {
  695.         set enfoldThis [getSelect]
  696.         beginningOfLine
  697.         killLine
  698.         insertText "# ◊◊◊◊ $enfoldThis ◊◊◊◊ #"
  699.         return
  700.     } 
  701.     elec::Insertion "# ◊◊◊◊ •• ◊◊◊◊ #"
  702. }
  703.  
  704. # vince's versions seems to have been left out, so here's mine -trf
  705. # If there is a selection, it get surrounded, if there is no selection,
  706. # but the cursor is touching the end of a word, it gets surrounded. 
  707. # Otherwise, we get a template (could not come up with a "stop beyond")
  708. proc surroundWithBullets {} {
  709.     if {[getPos]==[selEnd]}    {
  710.         set p [getPos]
  711.         backwardWord 
  712.         set sw [getPos]
  713.         forwardWord 
  714.         set ew [getPos]
  715.         goto $p
  716.         if {$p == $ew} {
  717.             select $sw $ew
  718.         } 
  719.     }
  720.     if {[isSelection]} {
  721.         set enfoldThis [getSelect]
  722.         deleteSelection
  723.         insertText "•$enfoldThis•"
  724.         return
  725.     } 
  726.     insertText "••"
  727.     backwardChar
  728.     elec::Insertion "•replace-this•"
  729. }
  730. # ◊◊◊◊ Info providers ◊◊◊◊ #
  731. #===============================================================================
  732.  
  733. ## 
  734.  # -------------------------------------------------------------------------
  735.  # 
  736.  # "TclOptionTitlebar" --
  737.  # 
  738.  #  Add corresponding extension/non-extension files.
  739.  # -------------------------------------------------------------------------
  740.  ##
  741. proc Tcl::OptionTitlebar {} {
  742.     if [package::active smarterSource] {
  743.         set n [win::CurrentTail]
  744.         if {[set a [string first + $n]] != -1} {
  745.             return "[string range $n 0 [expr $a -1]][file extension $n]"
  746.         } else {
  747.             global tclExtensionsFolder
  748.             pushd $tclExtensionsFolder
  749.             set f [glob -nocomplain "[file root $n]+*[file extension $n]"]
  750.             popd
  751.             return $f
  752.         }
  753.     } else {
  754.         return ""
  755.     }
  756. }
  757.  
  758. proc Tcl::DblClick {from to shift option control} {
  759.     
  760.     # if cmd and cntrl were pressed, we look to select part of
  761.     # a combination word (less any leading dollar sign) -trf
  762.     if {$control != 0} {
  763.         set clickedPos [getPos]    
  764.         if {[lookAt $from] == "\$"} {
  765.             incr from
  766.         } 
  767.         set sel_start $clickedPos 
  768.         set    selStartNotDetermined 1
  769.         while {$selStartNotDetermined && ($sel_start > $from)} {
  770.             set char [lookAt $sel_start] 
  771.             if {[regexp {_} $char]} {
  772.                 incr sel_start 
  773.                 set selStartNotDetermined 0
  774.             } elseif {[regexp {[A-Z]} $char]} {
  775.                 set selStartNotDetermined 0
  776.             } else {
  777.                 incr sel_start -1
  778.             } 
  779.         }
  780.         set sel_end   $clickedPos 
  781.         set    selEndNotDetermined 1
  782.         while {$selEndNotDetermined && ($sel_end <= $to)} {
  783.             set char [lookAt $sel_end] 
  784.             if {[regexp "\[A-Z_ \t\r\]" $char]} {
  785.                 set selEndNotDetermined 0
  786.             } else {
  787.                 incr sel_end 
  788.             } 
  789.         }
  790.         select $sel_start $sel_end 
  791.         return
  792.     } 
  793.     
  794.     # otherwise, we try to impart some extra info
  795.     select $from $to
  796.  
  797.     if [catch {Tcl::DblClickHelper [getSelect]}] {
  798.         message "No docs $shift $control $option"
  799.     }
  800. }
  801.  
  802.  
  803. # Now finds commands in Alpha Commands,
  804. # which has a <cr> immediately after them, e.g. beep, ticks.
  805. proc Tcl::DblClickHelper {text} {
  806.     global HOME auto_index auto_path
  807.     # Is it a loadable proc?
  808.     if {[string length [set f [procs::find $text]]]} {
  809.         editMark $f $text
  810.         return
  811.     }
  812.  
  813.     if {[info exists "auto_index($text)"]} {
  814.         editMark "$auto_index($text)" $text
  815.         return
  816.     }
  817.     # Is it a built-in Alpha command?
  818.     set lines [grep "^• $text\( |$)" "$HOME:Help:Alpha Commands"]
  819.     if {[string length $lines]} {
  820.         editMark "$HOME:Help:Alpha Commands" $text
  821.         setWinInfo read-only 1
  822.         return
  823.     }
  824.     # Is it a core Tcl command?
  825.     set lines [grep "^     $text -" "$HOME:Help:Tcl Commands"]
  826.     if {[string length $lines]} {
  827.         editMark "$HOME:Help:Tcl Commands" $text
  828.         setWinInfo read-only 1
  829.         return
  830.     }
  831.     # Is it a global variable?
  832.      if {[llength [info globals [string trimleft $text {$}]]]==1} {
  833.         showVarValue [string trimleft $text {$}]
  834.         return
  835.     }
  836.     # (becoming desperate) is it a mark in the current file?
  837.     if {[lsearch [getNamedMarks -n] ${text}] != -1} {
  838.         gotoMark $text
  839.         return
  840.     }
  841.     error ""
  842. }
  843.  
  844. #############################################################################
  845. #  Report the current value of a global variable, chosen interactively
  846. #  from a list of all active variables.
  847. #
  848. #  If the variable is an array, or its value is too big to fit in an 
  849. #  alertnote, then its contents are listed in a new window, otherwise 
  850. #  the variable's value is displayed in an alertnote.
  851. #
  852. proc getVarValue {} {
  853.     set def [getText [getPos] [selEnd]]
  854.     set var [listpick -p {Which var?} -L $def [lsort -ignore [info globals]]]
  855.     if {![string length $var]} return
  856.     showVarValue $var
  857. }
  858.  
  859. #############################################################################
  860. #  Report the current value of a global variable, chosen interactively
  861. #  from a list of all active variables.
  862. #
  863. #  If the variable is an array, or its value is too big to fit in an 
  864. #  alertnote, then its contents are listed in a new window, otherwise 
  865. #  the variable's value is displayed in an alertnote.
  866. #
  867. proc showVarValue {var} {
  868.     global $var
  869.     if {![catch {set $var} value]} {
  870.         viewValue $var $value
  871.         return
  872.     } else {
  873.         regsub -all : $var . var1
  874.         new -n "* $var1 *"
  875.         listArray $var
  876.     }
  877.     goto 0
  878.     # if 'shrinkWindow' is loaded, call it to trim the output window.
  879.     catch {shrinkWindow 2}
  880.     winReadOnly
  881.  
  882. #############################################################################
  883. #  List the name and value of each element of the array $arrName.
  884. #  (Convenient to use as a shell command.)
  885. #
  886. proc listArray {arrName} {
  887.     global $arrName
  888.     set lines {}
  889.     if {![catch {info vars $arrName}]} {
  890.         foreach nm [array names $arrName] {
  891.             # modified to handle odd named arrays -trf
  892.             set val [eval set \{$arrName\($nm\)\}]
  893.             append lines "\r\"$nm\"\t\{$val\}"
  894.         }
  895.         insertText $lines
  896.     } else {
  897.         alertnote "\"$arrName\" doesn't exist in this context"
  898.     }
  899. }
  900.  
  901. # ◊◊◊◊ Marking ◊◊◊◊ #
  902. # note: I put these procs in this order to reflect where you go to activate
  903. #  them, i.e. parseFuncsTcl via 'braces' pop-up, which is on top of the 
  904. # 'M' pop-up (invokes Tcl::MarkFile).
  905.  
  906. ## 
  907.  # -------------------------------------------------------------------------
  908.  #     
  909.  # "parseFuncsTcl" --
  910.  #    
  911.  #    This proc is called    by the "braces"    pop-up.    It returns a dynamically
  912.  #    created, alphabetical, list of    "pseudo-marks".
  913.  #    
  914.  #    Author:    Tom    Fetherston
  915.  # -------------------------------------------------------------------------
  916.  ## called by the "{}" button
  917. proc Tcl::parseFuncs {} {
  918.     global TclmodeVars
  919.     set end [maxPos]
  920.     set pos 0
  921.     set l {}
  922.     set markExpr {^[ \t]*((itcl(::|_))?class|body|proc|method|body)[ \t]}
  923.     set appearanceList {}
  924.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
  925.         set start [lindex $res 0]
  926.         set end [nextLineStart $start]
  927.         set t [getText $start $end]
  928.         switch [lindex $t 0] {
  929.             "proc" {
  930.                 set argLabel {}
  931.                 append argLabel [set word [lindex $t 1] ]
  932.                 #get the list of arguments
  933.                 set argsList [lindex $t 2]
  934.                 if {[llength $argsList] > 0} {
  935.                     append argLabel " \{"
  936.                     foreach arg $argsList {
  937.                         if {[llength $arg] == 2 } {
  938.                             append argLabel "¿"
  939.                         } elseif {[set arg] != "args"} {
  940.                             append argLabel "•"
  941.                         } else {
  942.                             append argLabel "…"
  943.                         }
  944.                     }
  945.                     append argLabel "\}"                    
  946.                 } 
  947.             }
  948.         }
  949.         if {[info exists cnts($word)]} {
  950.             # This section handles duplicate. i.e., overloaded names
  951.             set cnts($word) [expr $cnts($word) + 1]
  952.             set tailOfTag($word) " ($cnts($word) of $cnts($word))"
  953.             # we want the tag to point to its last occurence 
  954.             # because in Tcl, that proc will be 'in-force' when the
  955.             # file is loaded.
  956.             set indx($word) [lineStart [expr $start - 1]]
  957.         } else {
  958.             #SO do: remember the following
  959.             set cnts($word) 1
  960.             # if this is the only occurence of this proc, remember where it starts
  961.             set indx($word) [lineStart [expr $start - 1]]
  962.         }
  963.         #associate name and tag
  964.         set tag($word) $argLabel
  965.         
  966.         #advance pos to where we want to start the next search from
  967.         set pos $end
  968.     }
  969.  
  970.     set rtnRes {}
  971.     
  972.     if {[info exists indx]} {
  973.         foreach hn [lsort -ignore [array names indx]] {
  974.             set next [nextLineStart $indx($hn)]
  975.             set completeTag [set tag($hn)]
  976.             if {[info exists tailOfTag($hn)]} {
  977.                 append completeTag [ set tailOfTag($hn) ]
  978.             }
  979.             
  980.             lappend rtnRes $completeTag $next
  981.         }
  982.     }
  983.     return $rtnRes 
  984. }
  985.  
  986. # called by the "M" button
  987. proc Tcl::MarkFile {} {
  988.     global structuralMarks
  989.     set end [maxPos]
  990.     set pos 0
  991.     set l {}
  992.     if $structuralMarks {
  993.         set markExpr {^;?[     ]*((itcl(::|_))?class|proc|method|body|# ◊◊◊◊)[     ]}
  994.     } else {
  995.         set markExpr {^;?[     ]*((itcl(::|_))?class|proc|method|body)[     ]}
  996.     }
  997.     set class ""
  998.     set hasMarkers 0
  999.     while {![catch {search -s -f 1 -r 1 -m 0 -i 0 "$markExpr" $pos} res]} {
  1000.         set start [lindex $res 0]
  1001.         set end [nextLineStart $start]
  1002.         set t [getText $start $end]
  1003.         regsub -all {[\{\}]} [string trimleft $t ";"] {\\&} t
  1004.         switch -glob [lindex $t 0] {
  1005.             "proc" { set text [lindex $t 1] }
  1006.             "method" { set text ${class}::[lindex $t 1] }
  1007.             "body" { 
  1008.                 regexp {[a-zA-Z_][a-zA-Z_/0-9]*::[a-zA-Z_][a-zA-Z_/0-9]* } \
  1009.                   "[lindex $t 1] " text
  1010.             }
  1011.             "*class" { 
  1012.                 set class [lindex $t 1]
  1013.                 set text "${class} 000" 
  1014.             }
  1015.             "#" { 
  1016.                 regexp "# ◊◊◊◊ (.*) ◊◊◊◊ #" $t all text
  1017.                 if {[regexp "^(    )|(    )# ◊◊◊◊ " $t]} {
  1018.                     set text " •$text"
  1019.                 } else {
  1020.                     set text "•$text"
  1021.                 }                 
  1022.                 set hasMarkers 1
  1023.             }
  1024.         }
  1025.         set pos $end
  1026.         if {$structuralMarks} {
  1027.             lappend asEncountered $text
  1028.             set arr inds
  1029.         } else {
  1030.             if {[string index $t 0] == ";"} {
  1031.                 set arr iinds
  1032.             } else {
  1033.                 set arr inds
  1034.             }
  1035.         }
  1036.         set ${arr}($text) [lineStart [expr $start - 1]]
  1037.     }
  1038.  
  1039.     set already ""
  1040.     set class "#"
  1041.     foreach arr {inds iinds} {
  1042.         if {[info exists $arr]} {
  1043.             if {$arr == "iinds"} {
  1044.                 setNamedMark "-" 0 0 0
  1045.             }
  1046.             if $structuralMarks {
  1047.                 set order $asEncountered
  1048.             } else {
  1049.                 set order [lsort -ignore [array names $arr]]
  1050.             }
  1051.             foreach f $order {
  1052.                 if {[set el [set ${arr}($f)]] != 0} {
  1053.                     set next [nextLineStart $el]
  1054.                 } else {
  1055.                     set next 0
  1056.                 } 
  1057.                 
  1058.                 if { [string first "000" $f] != -1 } {
  1059.                     set ff "Class '[set class [lindex $f 0]]'"
  1060.                 } elseif { [string first "${class}::" $f] != -1 } {
  1061.                     set ff [string range $f [string length $class] end]
  1062.                 } else {
  1063.                     set ff $f
  1064.                 }
  1065.                 while { [lsearch -exact $already $ff] != -1 } {
  1066.                     set ff "$ff "
  1067.                 }
  1068.                 lappend already $ff
  1069.                 if {$hasMarkers && ![string match "•*" $ff] } {
  1070.                     set ff " $ff"
  1071.                 } 
  1072.                 setNamedMark $ff $el $next $next
  1073.             }
  1074.         }
  1075.     }
  1076. }
  1077.  
  1078. # ◊◊◊◊ Misc. ◊◊◊◊ #
  1079.  
  1080. ## 
  1081.  # -------------------------------------------------------------------------
  1082.  # 
  1083.  # "bind::tclContinueComment" --
  1084.  # 
  1085.  #  exploits a "feature" in the code that makes a new line a comment whenever 
  1086.  #  you are 'inside' a comment. This proc puts a pound sign at the end of the 
  1087.  #  current line, backsteps, and creates a new line. With the pound sign 
  1088.  #  present you are considered to be in a comment, so the bind::CarriageReturn 
  1089.  #  in the proc, and any subsequent bind::CarriageReturn called by a press of  
  1090.  #  the return key will provide another comment line automatically until the 
  1091.  #  pound sign at the end of the line is removed (killLine is handy for this).
  1092.  # -------------------------------------------------------------------------
  1093.  ##
  1094. proc bind::tclContinueComment {} {
  1095.     insertText {#}
  1096.     backwardChar
  1097.     bind::CarriageReturn
  1098. }
  1099. bind '\r' <c> bind::tclContinueComment Tcl
  1100.  
  1101. proc loadLine { pos } {
  1102.     goto $pos
  1103.     beginningLineSelect
  1104.     endLineSelect
  1105.     uplevel \#0 load    
  1106. }
  1107.  
  1108. #◊◊◊◊> 
  1109.  
  1110. loadRemoteSynchronise
  1111.